package com.zhoug.demo.viewpermission.page;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import com.uber.autodispose.AutoDispose;
import com.uber.autodispose.android.lifecycle.AndroidLifecycleScopeProvider;
import com.zhoug.common.adapters.recycler2.BaseRecyclerViewAdapter;
import com.zhoug.common.adapters.recycler2.BaseViewHolder;
import com.zhoug.common.framework.rxjava2.SchedulerUtils;
import com.zhoug.common.utils.JsonUtils;
import com.zhoug.common.utils.LogUtils;
import com.zhoug.common.utils.StringUtils;
import com.zhoug.demo.viewpermission.PrintTreeProvider;
import com.zhoug.demo.viewpermission.R;
import com.zhoug.demo.viewpermission.TreeProvider;
import com.zhoug.demo.viewpermission.Utils;
import com.zhoug.demo.viewpermission.network.HttpClient;
import com.zhoug.demo.viewpermission.network.NetWorkConfig;
import com.zhoug.demo.viewpermission.network.PageMenu;
import com.zhoug.logging.Logger;
import com.zhoug.viewpermission.Callback;
import com.zhoug.viewpermission.MenuDaoHelper;
import com.zhoug.viewpermission.MenuRepository;
import com.zhoug.viewpermission.MonitorControlPermissions;
import com.zhoug.viewpermission.NavigationMenu;
import com.zhoug.viewpermission.Optional;
import com.zhoug.viewpermission.ViewPermission;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import io.reactivex.Observable;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.disposables.Disposable;


public class MainActivity extends MyBaseActivity {
    private static final String TAG = ">>>MainActivity";
    private MenuListAdapter mMenuListAdapter;

    private Button mBtnUpdateMenu;
    private RecyclerView mRecyclerView;
    private Button mBtnSelect;
    private Button mBtnTest;
    private Button mBtnMonitor;

    @Override
    protected int getLayoutResId() {
        return R.layout.activity_main;
    }

    @Override
    protected void findViews() {
        mBtnUpdateMenu = findViewById(R.id.btn_updateMenu);
        mRecyclerView = findViewById(R.id.recyclerView);
        mBtnSelect = findViewById(R.id.btn_select);
        mBtnTest = findViewById(R.id.btn_test);
        mBtnMonitor = findViewById(R.id.btn_monitor);
    }

    @Override
    protected void onCreate1(Bundle savedInstanceState) {
        mMenuListAdapter = new MenuListAdapter();
        mMenuListAdapter.setData(new ArrayList<>());
        mRecyclerView.setAdapter(mMenuListAdapter);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(this));

        mBtnUpdateMenu.setOnClickListener(v -> {
            Map<String, Object> params = new HashMap<>();
            params.put("Token", NetWorkConfig.TOKEN);
            params.put("SystemCode", NetWorkConfig.SYSTEM_CODE);
            params.put("ClientType", NetWorkConfig.CLIENT_TYPE);
            HttpClient.get().getViewPermissionApi().getUserPermission(params)
                    .subscribeOn(SchedulerUtils.io())
                    .map(listHttpBaseResponse -> {
                        List<PageMenu> data = listHttpBaseResponse.getData();
                        Logger.d(TAG, "服务器菜单数量:" + (data != null ? data.size() : 0));
                        MenuDaoHelper.update(PageMenu.toNavigationMenus(data));
                        List<NavigationMenu> all = MenuDaoHelper.getAll();
                        Logger.d(TAG, "数据库菜单数:" + (all != null ? all.size() : 0));
                        all = buildTree(all);
                        sort(all);
                        return Optional.create(all);
                    })
                    .observeOn(SchedulerUtils.ui())
                    .as(AutoDispose.autoDisposable(AndroidLifecycleScopeProvider.from(this)))
                    .subscribe(optional -> {
                        List<NavigationMenu> data = optional.get();
                        logDivider("全部菜单树");
                        print(data);
                        mMenuListAdapter.loadSuccess(data);

                    }, throwable -> toast(throwable.getMessage()));
        });

        mBtnSelect.setOnClickListener(v -> {
            Disposable disposable = Observable
                    .create((ObservableOnSubscribe<Optional<List<NavigationMenu>>>) emitter -> {
                        List<NavigationMenu> all = MenuDaoHelper.getAll();
                        Logger.d(TAG, "数据库菜单数:" + (all != null ? all.size() : 0));
                        all = buildTree(all);
                        sort(all);
                        logDivider("全部菜单树");
                        print(all);
                        List<NavigationMenu> children = MenuDaoHelper.getRootMenus();
                        logDivider("根节点");

                        print(children);
                        if (all != null && !all.isEmpty()) {
                            NavigationMenu navigationMenu = all.get(0);
                            children = MenuDaoHelper.getChildrenByParentId(navigationMenu.getId());
                            logDivider(navigationMenu.getName() + ": 子菜单");
                            print(children);

                            navigationMenu = all.get(0);
                            children = MenuDaoHelper.getChildrenByParentId(navigationMenu.getId(), 5);
                            logDivider(navigationMenu.getName() + ": 递归子菜单 ByParentId");
                            print(children);

                            navigationMenu = all.get(0);
                            children = MenuDaoHelper.getChildrenByParentPath(navigationMenu.getPath(), 5);
                            logDivider(navigationMenu.getName() + ": 递归子菜单 ByParentPath");
                            print(children);


                            children = MenuDaoHelper.getChildrenByParentPath("/usercenter/myFrag");
                            logDivider("/usercenter/myFrag 子菜单");
                            print(children);

                        }

                        NavigationMenu byPath = MenuDaoHelper.getMenuByPath("/usercenter/myFrag");
                        Logger.d(TAG, "byPath:" + JsonUtils.toJson(byPath));

                        List<NavigationMenu> permissions = MenuDaoHelper.getPermissionsByMenuId("5078785815333333059");
                        logDivider("根据菜单id查询权限");
                        Logger.d(TAG, "onCreate1:" + JsonUtils.toJson(permissions));
                        permissions = MenuDaoHelper.getPermissionsByKey("userManager");
                        logDivider("根据权限标志查询权限");
                        Logger.d(TAG, "onCreate1:" + JsonUtils.toJson(permissions));

                        List<ViewPermission> permissionsByKeys = MenuDaoHelper.getPermissionsByKeys(Arrays.asList("userManager", "cestPer", "/yplt/firmList"));
                        logDivider("根据权限标志查询权限");
                        Logger.d(TAG, "getPermissionsByKeys:" + JsonUtils.toJson(permissionsByKeys));

                        emitter.onNext(Optional.create(all));
                        emitter.onComplete();

                    })
                    .compose(SchedulerUtils.apply())
                    .subscribe(s -> {
                        mMenuListAdapter.loadSuccess(s.get());
                    }, throwable -> {
                        toast(throwable.getMessage());
                        throwable.printStackTrace();
                    });


        });

        mBtnTest.setOnClickListener(v -> {
            startActivity(new Intent(this, TestActivity.class));
        });
        mBtnMonitor.setOnClickListener(v->{
            new MenuRepository(this)
                    .getMonitorControlPermissions(null, new Callback<MonitorControlPermissions>() {
                        @Override
                        public void onSuccess(MonitorControlPermissions data) {
                            if(data!=null){
                                LogUtils.d(TAG, "获取摄像头操作权限:{"+
                                        "\n录像:"+data.isRecordVideoEnable()+
                                        "\n截屏:"+data.isCaptureImageEnable()+
                                        "\n对讲:"+data.isTalkEnable()+
                                        "\n巡检:"+data.isInspectEnable()+
                                        "\n回放:"+data.isPlaybackEnable()+
                                        "\n静音:"+data.isMuteEnable()+
                                        "}"
                                        );

                            }
                        }

                        @Override
                        public void onFailure(String error) {
                            LogUtils.e(TAG,"获取摄像头操作权限失败:"+error);
                        }
                    });
        });
    }

    private void logDivider(String tag) {
        Logger.d(TAG, "##############+" + tag + "+#################");
    }

    private static void print(List<NavigationMenu> treeMenus) {
        Utils.printTree(treeMenus, 0, new PrintTreeProvider<NavigationMenu>() {
            @Override
            public List<NavigationMenu> getChildren(NavigationMenu pageMenu) {
                return pageMenu.getChildren();
            }

            @Override
            public String getPrintString(NavigationMenu pageMenu) {
                String description = pageMenu.getDescription();
                if (StringUtils.isNullOrEmpty(description)) {
                    return pageMenu.getName() + "-" + (pageMenu.getStatus() == 0 ? "正常" : "停用");
                }
                return MessageFormat.format("{0}【{1}】-{2}",
                        pageMenu.getName(),
                        description,
                        pageMenu.getStatus() == 0 ? "正常" : "停用");
            }
        });
    }


    public static void sort(List<NavigationMenu> menus) {
        if (menus == null || menus.isEmpty()) return;
        Collections.sort(menus, new Comparator<NavigationMenu>() {
            @Override
            public int compare(NavigationMenu o1, NavigationMenu o2) {
                return o1.getSortOrder() - o2.getSortOrder();
            }
        });
    }

    /**
     * 构建树形结构
     *
     * @param data
     * @return
     */
    private List<NavigationMenu> buildTree(List<NavigationMenu> data) {
        long startTime = System.currentTimeMillis();
        List<NavigationMenu> treeList = Utils.buildTree(data, new TreeProvider<NavigationMenu>() {
            @NonNull
            @Override
            public String getId(NavigationMenu data) {
                return data.getId();
            }

            @Nullable
            @Override
            public String getParentId(NavigationMenu data) {
                String parentId = data.getParentId();
                return StringUtils.isNullOrEmpty(parentId) ? null : parentId;
            }

            @Override
            public void setChildren(NavigationMenu parent, List<NavigationMenu> children) {
                parent.setChildren(children);
            }

            @Nullable
            @Override
            public List<NavigationMenu> getChildren(NavigationMenu data) {
                return data.getChildren();
            }
        });

        long endTime = System.currentTimeMillis();
        Logger.d(TAG, "buildTree:耗时:" + (endTime - startTime) + "毫秒");
        return treeList;
    }


    private class MenuListAdapter extends BaseRecyclerViewAdapter<NavigationMenu> implements View.OnClickListener {
        private NavigationMenu expandData;
        private List<String> expandIds = new ArrayList<>();


        private boolean isExpand(NavigationMenu pageMenu) {
            return expandIds.contains(pageMenu.getId());
        }

        private void openExpand(NavigationMenu pageMenu) {
            expandIds.add(pageMenu.getId());
        }

        private void closeExpand(NavigationMenu pageMenu) {
            expandIds.remove(pageMenu.getId());
        }


        @Override
        protected int getLayoutId(int viewType) {
            return R.layout.menu_list_item;
        }

        @Override
        protected void onBindData(BaseViewHolder holder, NavigationMenu data, int position, int viewType) {
            TextView mTvInfo = holder.itemView.findViewById(R.id.tv_info);
            TextView mTvName = holder.itemView.findViewById(R.id.tv_name);
            RecyclerView mRecyclerViewChild = holder.itemView.findViewById(R.id.recyclerViewChild);
            if (data != null) {
                String description = data.getDescription();
                if (StringUtils.isNullOrEmpty(description)) {
                    mTvName.setText(data.getName());
                } else {
                    mTvName.setText(MessageFormat.format("{0}({1})", data.getName(), data.getDescription()));
                }
                List<NavigationMenu> child = data.getChildren();
                if (child != null && !child.isEmpty()) {
                    MenuListAdapter childAdapter = (MenuListAdapter) mRecyclerViewChild.getAdapter();
                    if (childAdapter == null) {
                        childAdapter = new MenuListAdapter();
                        mRecyclerViewChild.setAdapter(childAdapter);
                        mRecyclerViewChild.setLayoutManager(new LinearLayoutManager(getActivity()));
                    }
                    childAdapter.setData(child);
                    if (isExpand(data)) {
                        mRecyclerViewChild.setVisibility(View.VISIBLE);
                    } else {
                        mRecyclerViewChild.setVisibility(View.GONE);
                    }
                    mTvName.setTag(position);
                    mTvName.setOnClickListener(this);
                } else {
                    mRecyclerViewChild.setVisibility(View.GONE);
                }
                mTvName.setClickable(true);
                mTvName.setTag(position);
                mTvName.setOnClickListener(this);
                mTvInfo.setClickable(true);
                mTvInfo.setTag(position);
                mTvInfo.setOnClickListener(this);

            }

        }

        @Override
        public void onClick(View v) {
            NavigationMenu itemData = getItemData((Integer) v.getTag());
            int id = v.getId();
            if (id == R.id.tv_info) {
                //查看菜单
                PageMenuInfoFragment pageMenuInfoFragment = new PageMenuInfoFragment(itemData);
                pageMenuInfoFragment.show(getSupportFragmentManager(), PageMenuInfoFragment.class.getCanonicalName());

            } else {
                List<NavigationMenu> child = itemData.getChildren();
                if (child == null || child.isEmpty()) {
                    return;
                }
                if (isExpand(itemData)) {
                    closeExpand(itemData);
                } else {
                    openExpand(itemData);
                }
                notifyDataSetChanged();
            }
        }
    }


}